"""
本地引擎
"""
import os
import sys
import time
import threading
from typing import Optional, Dict, Any

# 添加接口层路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

try:
    from src.frontend.backend_interface import get_backend_interface, cleanup_backend_interface

    HAS_INTERFACE = True
except ImportError:
    print("警告：无法导入后端接口")
    HAS_INTERFACE = False


class LocalEngine:
    """本地引擎 - 前后端接口层"""

    def __init__(self, display_module=None, control_panel=None):
        self.display = display_module
        self.control = control_panel

        # 后端接口
        self.backend_interface = None
        if HAS_INTERFACE:
            self.backend_interface = get_backend_interface()

        # 运行状态
        self.running = False
        self.ai_control = True
        self.is_training = False

        # 状态缓存
        self.last_state = None
        self.last_stats = {}

        # 更新线程
        self.update_thread = None

        # 初始化连接
        self._initialize_connections()

        print("本地引擎（接口层）初始化完成")

    def _initialize_connections(self):
        """初始化前后端连接"""
        if not self.backend_interface:
            if self.control:
                self.control.add_message("后端接口不可用")
            return

        # 设置后端接口到组件
        if self.display:
            self.display.set_backend_interface(self.backend_interface)

        if self.control:
            self.control.set_backend_interface(self.backend_interface)

        # 注册监听器
        self.backend_interface.add_state_listener(self._on_state_update)
        self.backend_interface.add_stats_listener(self._on_stats_update)
        self.backend_interface.add_message_listener(self._on_message)

        # 检查连接状态
        if self.backend_interface.is_connected():
            if self.control:
                self.control.add_message("后端连接成功")
        else:
            if self.control:
                self.control.add_message("后端连接失败")

    def _on_state_update(self, state: Dict[str, Any]):
        """处理状态更新"""
        self.last_state = state

        # 更新显示模块
        if self.display:
            stats = self.last_stats.copy()
            # 从状态中提取统计信息
            if "player" in state:
                stats.update({
                    "health": state["player"].get("hp", 100),
                    "score": state.get("score", 0),
                    "round": state.get("round", 0)
                })

            self.display.update_from_backend(state, stats)

    def _on_stats_update(self, stats: Dict[str, Any]):
        """处理统计更新"""
        self.last_stats.update(stats)

        # 更新控制面板
        if self.control:
            self.control.update_stats(stats)

        # 更新显示模块
        if self.display and self.last_state:
            self.display.update_from_backend(self.last_state, stats)

    def _on_message(self, message: str):
        """处理消息"""
        if self.control:
            self.control.add_message(message)

    # =========================
    # 游戏控制接口
    # =========================

    def reset(self):
        """重置游戏"""
        if self.backend_interface:
            self.backend_interface.reset_game()
        else:
            if self.control:
                self.control.add_message("后端接口不可用")

    def manual_action(self, action: int):
        """执行手动动作"""
        if not self.backend_interface:
            if self.control:
                self.control.add_message("后端接口不可用")
            return

        if self.ai_control:
            if self.control:
                self.control.add_message("请先切换到手动控制模式")
            return

        # 执行动作（异步）
        self.backend_interface.execute_action(action)

        # 动作反馈
        action_names = ["右", "下", "左", "上"]
        if 0 <= action < len(action_names):
            action_name = action_names[action]
            if self.control:
                self.control.add_message(f"执行动作: {action_name}")

    def set_ai_control(self, enabled: bool):
        """设置AI控制模式"""
        self.ai_control = enabled

        if self.backend_interface:
            self.backend_interface.set_ai_control(enabled)

        mode = "AI控制" if enabled else "手动控制"
        if self.control:
            self.control.add_message(f"切换到{mode}模式")

    # =========================
    # 训练控制接口
    # =========================

    def startTraining(self, hyperparams: Dict[str, Any] = None):
        """开始训练"""
        if not self.backend_interface:
            if self.control:
                self.control.add_message("后端接口不可用，无法训练")
            return

        # 默认超参数
        default_params = {
            "learning_rate": 0.001,
            "epsilon": 0.1,
            "speed": 1.0,
            "batch_size": 64,
            "target_update": 100
        }

        if hyperparams:
            default_params.update(hyperparams)

        self.is_training = True
        self.backend_interface.start_training(default_params)

        if self.control:
            self.control.add_message("训练请求已发送")

    def stopTraining(self):
        """停止训练"""
        self.is_training = False

        if self.backend_interface:
            self.backend_interface.stop_training()

        if self.control:
            self.control.add_message("停止训练请求已发送")

    # =========================
    # 模型管理接口
    # =========================

    def saveModel(self, name: str = None):
        """保存模型"""
        if not self.backend_interface:
            if self.control:
                self.control.add_message("后端接口不可用")
            return

        model_name = name or f"model_{int(time.time())}"
        self.backend_interface.save_model(model_name)

        if self.control:
            self.control.add_message(f"保存模型请求已发送: {model_name}")

    def loadModel(self, path: str):
        """加载模型"""
        if not self.backend_interface:
            if self.control:
                self.control.add_message("后端接口不可用")
            return

        if not os.path.exists(path):
            if self.control:
                self.control.add_message(f"模型文件不存在: {path}")
            return

        self.backend_interface.load_model(path)

        if self.control:
            self.control.add_message(f"加载模型请求已发送: {path}")

    # =========================
    # 显示控制接口
    # =========================

    def toggleRendering(self, enabled: bool):
        """切换渲染（纯UI功能）"""
        # 这个功能现在由显示模块直接处理
        if self.control:
            status = "启用" if enabled else "禁用"
            self.control.add_message(f"渲染{status}")

    def freezeModel(self, frozen: bool):
        """冻结模型（后端功能）"""
        # 这个功能需要后端支持
        if self.control:
            status = "冻结" if frozen else "解冻"
            self.control.add_message(f"模型{status}请求（需要后端支持）")

    def set_hud(self, enabled: bool):
        """设置HUD显示"""
        if self.display:
            self.display.toggleHUD(enabled)

        if self.control:
            status = "启用" if enabled else "禁用"
            self.control.add_message(f"HUD显示{status}")

    # =========================
    # 状态查询接口
    # =========================

    def get_game_state(self) -> Optional[Dict[str, Any]]:
        """获取当前游戏状态"""
        if self.backend_interface:
            return self.backend_interface.get_game_state()
        return self.last_state

    def get_training_stats(self) -> Dict[str, Any]:
        """获取训练统计"""
        if self.backend_interface:
            return self.backend_interface.get_training_stats()
        return self.last_stats

    def is_backend_connected(self) -> bool:
        """检查后端连接状态"""
        if self.backend_interface:
            return self.backend_interface.is_connected()
        return False

    # =========================
    # 运行控制
    # =========================

    def start(self):
        """启动引擎"""
        self.running = True

        # 启动更新循环
        self.update_thread = threading.Thread(target=self._update_loop, daemon=True)
        self.update_thread.start()

        if self.control:
            self.control.add_message("本地引擎已启动")

    def stop(self):
        """停止引擎"""
        self.running = False

        # 停止训练
        if self.is_training:
            self.stopTraining()

        # 等待更新线程结束
        if self.update_thread:
            self.update_thread.join(timeout=2)

        if self.control:
            self.control.add_message("本地引擎已停止")

    def _update_loop(self):
        """更新循环（用于兼容性）"""
        while self.running:
            try:
                # 定期检查连接状态
                if self.backend_interface and not self.backend_interface.is_connected():
                    if self.control:
                        self.control.add_message("后端连接断开")

                time.sleep(1.0)  # 每秒检查一次

            except Exception as e:
                print(f"更新循环错误: {e}")
                time.sleep(1.0)

    def update(self):
        """手动更新（用于兼容旧接口）"""
        # 现在状态更新是异步的，这个方法保持为兼容性
        pass

    # =========================
    # 生命周期管理
    # =========================

    def cleanup(self):
        """清理资源"""
        self.stop()

        # 保存自动备份
        if self.backend_interface and self.backend_interface.is_connected():
            self.saveModel("autosave")

        # 清理后端接口
        if self.backend_interface:
            self.backend_interface.remove_state_listener(self._on_state_update)
            self.backend_interface.remove_stats_listener(self._on_stats_update)
            self.backend_interface.remove_message_listener(self._on_message)

        if self.control:
            self.control.add_message("本地引擎已清理")

    # =========================
    # 兼容性方法（用于旧接口）
    # =========================

    def run_training_step(self):
        """运行训练步骤（兼容性方法）"""
        # 现在训练由后端自动处理
        pass

    def get_action(self, state):
        """获取动作（兼容性方法）"""
        # 现在动作选择由后端处理
        return 0

    def step(self, action):
        """执行步骤（兼容性方法）"""
        # 现在通过接口执行
        if not self.ai_control:
            self.manual_action(action)

    # =========================
    # 调试和测试方法
    # =========================

    def test_backend_connection(self):
        """测试后端连接"""
        if not self.backend_interface:
            message = "后端接口未初始化"
        elif self.backend_interface.is_connected():
            state = self.backend_interface.get_game_state()
            stats = self.backend_interface.get_training_stats()
            message = f"后端连接正常，状态: {bool(state)}, 统计: {bool(stats)}"
        else:
            message = "后端连接失败"

        if self.control:
            self.control.add_message(message)
        print(message)

        return self.backend_interface and self.backend_interface.is_connected()

    def force_state_refresh(self):
        """强制刷新状态"""
        if self.backend_interface:
            state = self.backend_interface.get_game_state()
            stats = self.backend_interface.get_training_stats()

            if state:
                self._on_state_update(state)
            if stats:
                self._on_stats_update(stats)

            if self.control:
                self.control.add_message("状态已强制刷新")

    def get_debug_info(self) -> Dict[str, Any]:
        """获取调试信息"""
        return {
            "running": self.running,
            "ai_control": self.ai_control,
            "is_training": self.is_training,
            "backend_connected": self.is_backend_connected(),
            "has_display": bool(self.display),
            "has_control": bool(self.control),
            "last_state_keys": list(self.last_state.keys()) if self.last_state else [],
            "last_stats_keys": list(self.last_stats.keys())
        }